package example.listview;

import com.google.appengine.preferencessync.MergeHandler;

import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.os.IBinder;

/**
 * Sample merge service class for merging. Receives updates from the server.
 * Called if the CUSTOM_WINS merge strategy is set. This service class should have
 * android:name="com.google.appengine.preferencessync.merge" in android manifest.
 */
public class MergeService extends Service {
  
  /**
   * The Merge handler class to be returned on onBind().
   * As soon as the sync adapter receives all the updates from the server, 
   * it calls the merge handler provided CUSTOM_WINS strategy is set for
   * the preference.
   * The call occurs in the following order:
   *      Sync cycle for SharedPreference file X:
   *        if CUSTOM_WINS set for X
   *          call merge service and get merge handler object H
   *          H.onMergeStarted(X);
   *          for each change received from the server:
   *            if change is an update
   *              H.onUpdate(key, value)
   *            if change is a delete 
   *              H.onDelete(key)
   *          H.onMergeFinished()
   */
  private static class Handler extends MergeHandler {
    private final Context context; 
    
    Editor editor;
    SharedPreferences sp;
    
    public Handler(Context context) {
      this.context = context;
    }
    
    @Override
    public void onMergeFinished() {
      editor.commit();
    }

    @Override
    public void onMergeStarted(String arg0) {
      sp = context.getSharedPreferences(arg0, Context.MODE_PRIVATE);
      editor = sp.edit();
    }

    @Override
    public void onDelete(String arg0) {
      editor.remove(arg0);
    }
    
   @Override
    public void onUpdate(String arg0, Object arg1) {
      // Simple merge function assumes arg1, i.e the value, is a string.
      // Decides update priority based on a simple case compare.
      if (arg1 instanceof String) {
        String str = sp.getString(arg0, null);
        if (str == null || str.compareToIgnoreCase((String) arg1) < 0) {
          editor.putString(arg0, (String) arg1);
        }
      }
    }
  }

  @Override
  public IBinder onBind(Intent intent) {
    return new Handler(getApplicationContext());
  }
}
